package edu.ccut.saturn.component.loader.node;

/**
 * 用于解析logic组件配置文件中“工作流”结点的加载类。
 * <p>继承了<code>NodeInfoLoader</code>,并实现了<code>loadNode</code>方法。<p>
 * 
 * @author 温建
 * @version 1.0 2008.8.18
 * 
 * @see <code>WorkFlowNodeInfo</code>
 */
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Element;
import org.osgi.framework.Bundle;

import edu.ccut.saturn.component.INodeInfo;
import edu.ccut.saturn.component.IParameterInfo;
import edu.ccut.saturn.component.SaturnComponentException;
import edu.ccut.saturn.component.impl.node.WorkFlowNodeInfo;

public class WorkFlowNodeInfoLoader extends NodeInfoLoader {

	public static final String KEY_NODETYPE_WORKFLOW = "workflow";

	public static final String KEY_WORKFLOW_VERSION = "version";

	public static final String KEY_NODE_START_TRANSACTION = "transaction";

	public static final String KEY_LOGIC_TRANSACTION_TYPE = "type";

	public static final String TRANSACTION_TYPE_REQUIRENEW = "requireNew";

	@SuppressWarnings("unchecked")
	public List<INodeInfo> loadNode(Element root, Bundle bundle)
			throws SaturnComponentException {

		List<Element> workFlowElements = root.elements(KEY_NODETYPE_WORKFLOW);

		List<INodeInfo> workFlowNodeInfos = new ArrayList<INodeInfo>(
				workFlowElements.size());

		for (Element workFlowElement : workFlowElements) {
			String key = workFlowElement.elementTextTrim(KEY_NODE_KEY);
			String x = workFlowElement.attributeValue(KEY_NODE_X).trim();
			String y = workFlowElement.attributeValue(KEY_NODE_Y).trim();
			String version = workFlowElement
					.elementTextTrim(KEY_WORKFLOW_VERSION);

			Element transaction = workFlowElement
					.element(KEY_NODE_START_TRANSACTION);

			String transactionType = null;

			if (transaction != null) {
				transactionType = transaction
						.attributeValue(KEY_LOGIC_TRANSACTION_TYPE);
			}

			if (transactionType == null || "".equals(transactionType)) {
				transactionType = TRANSACTION_TYPE_REQUIRENEW;
			}

			try {
				List<IParameterInfo> parameters = getParameterInfos(bundle,
						workFlowElement);

				String id = workFlowElement.attributeValue(KEY_NODE_ID).trim();
				String name = workFlowElement.elementTextTrim(KEY_NODE_NAME);
				String description = workFlowElement
						.elementTextTrim(KEY_NODE_DESCRIPTION);

				String nextId = workFlowElement.attributeValue(KEY_NODE_NEXT)
						.trim();

				String exceptionId = workFlowElement.attributeValue(
						KEY_NODE_EXCEPTION).trim();

				logger.debug("  load workflow node id = \"" + id + "\" key = \"" 
						+ key + "\" name = \"" + name + "\" description = \""
						+ description + "\" nextId = \"" + nextId + "\"");
				
				WorkFlowNodeInfo workFlowNodeInfo = new WorkFlowNodeInfo(key,
						id, name, description, nextId, parameters, version,
						transactionType, exceptionId, x, y);

				workFlowNodeInfos.add(workFlowNodeInfo);

			} catch (Exception e) {
				logger.error("load workflow node failed! the key is [" + key
						+ "]", e);

				throw new SaturnComponentException(
						"load workflow node failed! the key is [" + key + "]",
						e);
			}
		}
		return workFlowNodeInfos;
	}
}
